package com.justgame.project.base.websocket;

import com.justgame.project.base.config.WebSocketConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * WebSocket推送服务
 */
@Slf4j
@Component
@ServerEndpoint(value = "/link", configurator = WebSocketConfig.class)
public class SocketApi {
    private static AtomicInteger onlineCount = new AtomicInteger(0);
    private static volatile List<Map<String, Session>> clients = new CopyOnWriteArrayList<>();
    private Session session;
    private HttpSession httpSession;

    public static void sendMessage(String msg, Session toSession) {
        try {
            toSession.getBasicRemote().sendText(msg);
        } catch (Exception e) {
        }
    }

    /* 群发message */
    public static void sendGroupMessage(Object msgObj, Session toSession) {
        try {
            toSession.getBasicRemote().sendObject(msgObj);
        } catch (Exception e) {
        }
    }

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        this.session = session;
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        boolean flag = true;
        for (Map<String, Session> map : clients) {
            if (!map.containsKey(httpSession.getId())) {
                flag = false;
            } else {
                clients.remove(map);
                break;
            }
        }

        if (flag) {
            Map<String, Session> update = new HashMap<>();
            update.put(httpSession.getId(), session);
            clients.add(update);
            log.info("{}已重连！", httpSession.getId());
        } else {
            Map<String, Session> map = new HashMap<>();
            map.put(httpSession.getId(), session);
            clients.add(map);
            onlineCount.incrementAndGet();
            log.info("新用户登录：{},当前在线人数：{}", session.getId(), onlineCount.get());
        }
    }

    @OnClose
    public void onClose(Session session) {
        if (clients.contains(session)) {
            onlineCount.decrementAndGet();
            log.info("用户退出登录：{},当前在线人数：{}", session.getId(), onlineCount.get());
        }
    }

    @OnMessage
    public void onMsg(String message, Session session) {
        if (message.equals("ping")) {
            this.sendMessage("pong", session);
        }
    }

    @OnError
    public void onError(Session session, Throwable e) {
        log.info("与{}间Socket发生错误", session.getId());
        e.printStackTrace();
    }

}
